package charlie.shop.web;

import charlie.shop.misc.Common;
import com.charlie.beans.ShipmentOrder;
import com.charlie.beans.Users;
import com.charlie.beans.Warehouse;
import com.charlie.mail.MailLocal;
import com.charlie.mail.MailTemplate;
import com.charlie.mail.MailTemplateType;
import com.charlie.map.MapLocal;
import com.charlie.sessions.CartLocal;
import com.charlie.sessions.ShipmentOrderFacadeLocal;
import com.charlie.sessions.UsersFacadeLocal;
import com.charlie.sessions.WarehouseFacadeLocal;
import java.io.IOException;
import javax.ejb.EJB;
import javax.persistence.NoResultException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 
 * 
 * @author Vitaliy Mostipaka <imprtat@gmail.com>
 */
@WebServlet(name = "OrderServlet", urlPatterns = {"/order"})
public class OrderServlet extends HttpServlet {

    @EJB
    private WarehouseFacadeLocal warehouse;
    @EJB
    private ShipmentOrderFacadeLocal so;
    @EJB
    private MailLocal mail;
    @EJB
    private MapLocal map;
    @EJB
    private UsersFacadeLocal users;

    private CartLocal checkCart(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        CartLocal cart = (CartLocal) request.getSession(true).getAttribute("cart");
        if (cart == null || cart.getItemsAmount() == 0) {
            response.sendRedirect(getServletContext().getContextPath() + "/cart");
            return null;
        }
        return cart;
    }
    /**
     * Calculate shipping cost for warehouse wh
     * @param wh warehouse
     * @param distance distance
     * @return 
     */
    private int getShipmentCost(Warehouse wh, int distance) {
        return distance * wh.getShipmentRate() / 1000;
    }

    /**
     * Handles the HTTP
     * <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        CartLocal cart = checkCart(request, response);
        if (cart == null) {
            return;
        }
        request.setAttribute("warehouse_list", warehouse.findAll());
        request.getRequestDispatcher("/order/delivery.jsp").forward(request, response);
    }

    /**
     * Handles the HTTP
     * <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Users user = (Users) request.getSession(true).getAttribute("user");
        CartLocal cart = checkCart(request, response);
        if (cart == null) {
            return;
        }

        String destination;
        if (user != null && user.getLocation().length() > 0) {
            destination = user.getLocation();
        } else {
            destination = request.getParameter("destination");
        }
        if (destination != null && destination.length() > 0) {
            cart.setLocation(destination);
        }

        Warehouse wh;
        try {
            int warehouse_id = Integer.parseInt(request.getParameter("warehouse_id"));
            wh = warehouse.find(warehouse_id);
            cart.setWarehouse(warehouse_id);
        } catch (NoResultException ex) {
            response.sendRedirect(getServletContext().getContextPath() + "/order");
            return;
        }

        response.setContentType("text/html;charset=UTF-8");

        int distance = Common.getParametrInt(request, "distance", 0);
        int items_cost = cart.getCost();
        int delivery_cost = 0;
        String complete = request.getParameter("complete");
        if (complete != null && complete.equals("1")) {
            String email;
            String notify = request.getParameter("notify");
            cart.setNotify(false);
            if (notify != null && notify.equals("on")) {
                cart.setNotify(true);
            }
            if (user != null) {
                email = user.getEmail();
            } else {
                email = request.getParameter("email");
                boolean check_email = cart.getNotify() || (!cart.getNotify() && email == null);
                if ((check_email && !users.emailIsValid(email))) {
                    request.setAttribute("distance", distance);
                    request.setAttribute("delivery_cost", getShipmentCost(wh, distance));
                    request.setAttribute("items_cost", items_cost);
                    request.setAttribute("total_price", items_cost + delivery_cost);
                    request.getRequestDispatcher("/order/complete.jsp").forward(request, response);
                    return;
                }
            }
            cart.setEmail(email);

            distance = map.getDestination(wh.getLocation(), cart.getLocation());
            if (distance < 1) {
                request.getRequestDispatcher("/order/delivery.jsp").forward(request, response);
                return;
            }
            delivery_cost = getShipmentCost(wh, distance);

            ShipmentOrder order = so.createFromCart(cart);
            cart.clear();
            order.setShipingCost(delivery_cost);
            so.edit(order);

            if (order != null) {
                request.setAttribute("tracking_number", order.getSoId());
                request.getRequestDispatcher("/order/track.jsp").forward(request, response);
                if (cart.getNotify()) {
                    MailTemplate tpl = new MailTemplate(MailTemplateType.NEW_ORDER);
                    tpl.setParametr("name", user.getFirstName());
                    mail.send(email, "New order in CharlieShop", tpl);
                }
                return;
            }
        } else {
            try {
                delivery_cost = getShipmentCost(wh, distance);
            } catch (NoResultException ex) {
            }
        }

        request.setAttribute("distance", distance);
        request.setAttribute("warehouse_addr", wh.getLocation());
        request.setAttribute("items_cost", items_cost);
        request.setAttribute("delivery_cost", delivery_cost);
        request.setAttribute("total_price", items_cost + delivery_cost);

        request.getRequestDispatcher("/order/complete.jsp").forward(request, response);
    }    
}
